X if (bufset((unsigned int)(first_length + write_length)) == -1)
X return -1;
X
X if (quiet_procmget(GLOBALdipc, (unsigned long)exent.ex_u.exunix.rootaddrs.addrvec, sys_call_buf, first_length) == -1)
X return -1;
X
X exent.ex_u.exunix.rootaddrs.addrvec = (struct sockaddr *)sys_call_buf;
X break;
X
X case AUTH_DES:
X /*
X * No thanks -- I'll wait till I see it used.
X */
X return -2;
X
X default:
X return -2;
X }
X
X if (exent.ex_flags & EX_RDMOSTLY)
X {
X if (quiet_procmget(GLOBALdipc, (unsigned long)exent.ex_writeaddrs.addrvec, sys_call_buf + first_length, write_length) == -1)
X return -1;
X
X exent.ex_writeaddrs.addrvec = (struct sockaddr *)(sys_call_buf + first_length);
X }
X
X exp = &exent;
X }
X
X Rstart;
X return_value0 = syscall(syscallno, dirnamep, exp);
X return_errno = errno;
X Rstop;
X
X return 0;
X}
X
Xstatic
Xint
Xsys_fcntl(syscallno)
Xint syscallno;
X{
X switch ((int)arg[1])
X {
X case BSD43_F_DUPFD:
X Rstart;
X return_value0 = syscall(BSD43_SYS_dup, fd_lookup((int)arg[0]));
X return_errno = errno;
X Rstop;
X
X if (return_value0 != -1)
X {
X int newfd;
X int nfiles;
X
X for (nfiles = fd_nfiles(), newfd = (int)arg[2]; newfd < nfiles && fd_lookup(newfd) != -1; newfd++)
X ;
X
X if (newfd >= nfiles)
X {
X (void)close(return_value0);
X errno = EMFILE;
X return 0;
X }
X
X fd_dopen(return_value0, newfd);
X
X return_value0 = newfd;
X }
X break;
X
X case BSD43_F_GETFD:
X case BSD43_F_SETFD:
X case BSD43_F_GETFL:
X case BSD43_F_SETFL:
X case BSD43_F_SETOWN:
X Rstart;
X return_value0 = syscall(syscallno, fd_lookup((int)arg[0]), (int)arg[1], (int)arg[2]);
X return_errno = errno;
X Rstop;
X break;
X
X default:
X return -2;
X }
X
X return 0;
X}
X
Xstatic
Xint
Xsys_fstat(syscallno)
Xint syscallno;
X{
X return generic_fstat(syscallno, sizeof(struct bsd43_stat));
X}
X
Xstatic
Xint
Xsys_fstatfs(syscallno)
Xint syscallno;
X{
X struct bsd43_statfs *bufp;
X
X if (dmget(arg[1], sizeof(*bufp), &bufp) == -1)
X return -1;
X
X Rstart;
X return_value0 = syscall(syscallno, arg[0], bufp);
X return_errno = errno;
X Rstop;
X
X if (mput(arg[1], bufp, sizeof(*bufp), return_value0) == -1)
X return -1;
X
X return 0;
X}
X
Xstatic
Xint
Xsys_getgid(syscallno)
Xint syscallno;
X{
X /*
X * TODO: second return value for BSD43 getgid().
X */
X Rstart;
X return_value0 = syscall(syscallno);
X return_value1 = getegid(); /* Not really correct. */
X return_errno = errno;
X Rstop;
X
X return 0;
X}
X
Xstatic
Xint
Xsys_getgroups(syscallno)
Xint syscallno;
X{
X return generic_getgroups(syscallno, BSD43_NGROUPS);
X}
X
Xstatic
Xint
Xsys_getitimer(syscallno)
Xint syscallno;
X{
X return generic_getitimer(syscallno, sizeof(struct bsd43_itimerval));
X}
X
Xstatic
Xint
Xsys_getpgrp(syscallno)
Xint syscallno;
X{
X Rstart;
X return_value0 = syscall(syscallno, (int)arg[0]);
X return_errno = errno;
X Rstop;
X
X return 0;
X}
X
Xstatic
Xint
Xsys_getrlimit(syscallno)
Xint syscallno;
X{
X return generic_getrlimit(syscallno, sizeof(struct bsd43_rlimit));
X}
X
Xstatic
Xint
Xsys_getrusage(syscallno)
Xint syscallno;
X{
X return generic_getrusage(syscallno, sizeof(struct bsd43_rusage));
X}
X
Xstatic
Xint
Xsys_gettimeofday(syscallno)
Xint syscallno;
X{
X struct bsd43_timeval tv;
X struct bsd43_timezone tz;
X
X return generic_gettimeofday(syscallno, &tv, sizeof(tv), &tz, sizeof(tz));
X}
X
Xstatic
Xint
Xsys_getuid(syscallno)
Xint syscallno;
X{
X /*
X * TODO: second return value for BSD43 getuid().
X */
X Rstart;
X return_value0 = syscall(syscallno);
X return_value1 = geteuid(); /* Not really correct. */
X return_errno = errno;
X Rstop;
X
X return 0;
X}
X
Xtypedef union bsd43_ifcu bsd43_ifcu;
Xunion bsd43_ifcu
X{
X caddr_t ifcu_buf;
X struct ifreq *ifcu_req;
X};
X
Xtypedef struct bsd43_ifconf bsd43_ifconf;
Xstruct bsd43_ifconf
X{
X int ifc_len; /* size of associated buffer */
X bsd43_ifcu ifc_ifcu;
X};
X
X#define ifconf bsd43_ifconf
X
X/*
X * See /bsd43/usr/include/sys/ioctl.h.
X */
Xstatic
Xint
Xsys_ioctl(syscallno)
Xint syscallno;
X{
X int length;
X int need_copy_in;
X int need_copy_out;
X char iocbuf[BSD43_IOCPARM_MASK];
X bsd43_ifconf *ifp;
X caddr_t saved_ifcu_buf;
X
X if ((arg[1] & (unsigned long)(BSD43_IOC_INOUT | BSD43_IOC_VOID)) == 0)
X return sysv_sys_ioctl();
X
X need_copy_in = arg[1] & (unsigned long)BSD43_IOC_IN;
X need_copy_out = arg[1] & (unsigned long)BSD43_IOC_OUT;
X length = (arg[1] >> (unsigned long)16) & (unsigned long)BSD43_IOCPARM_MASK;
X
X if (need_copy_in)
X {
X if (quiet_procmget(GLOBALdipc, (unsigned long)arg[2], &iocbuf[0], length) == -1)
X return -1;
X }
X
X /*
X * Sadly, the bsd43 ioctl encoding scheme only handles
X * one level of indirection, so ...
X */
X switch (arg[1])
X {
X case BSD43_SIOCGIFCONF:
X /*
X * if(7)
X */
X ifp = (bsd43_ifconf *)&iocbuf[0];
X
X if (bufset((unsigned int)ifp->ifc_len) == -1)
X return -1;
X
X saved_ifcu_buf = ifp->ifc_ifcu.ifcu_buf;
X ifp->ifc_ifcu.ifcu_buf = sys_call_buf;
X break;
X }
X
X /*
X * TODO: But what about fd's hidden in ioctl() args?
X * strioctl() calls, for example.
X */
X Rstart;
X return_value0 = syscall(syscallno, fd_lookup((int)arg[0]), (int)arg[1], &iocbuf[0]);
X return_errno = errno;
X Rstop;
X
X if (return_value0 != -1 && need_copy_out)
X {
X switch (arg[1])
X {
X case BSD43_SIOCGIFCONF:
X ifp = (bsd43_ifconf *)&iocbuf[0];
X
X if (quiet_procmput(GLOBALdipc, (unsigned long)saved_ifcu_buf, sys_call_buf, ifp->ifc_len) == -1)
X return -1;
X
X ifp->ifc_ifcu.ifcu_buf = saved_ifcu_buf;
X break;
X }
X
X if (quiet_procmput(GLOBALdipc, (unsigned long)arg[2], &iocbuf[0], length) == -1)
X return -1;
X }
X
X return 0;
X}
X
X/*
X * Global entry point so that the sysv ioctl()
X * can call the bsd43 ioctl() when it finds that
X * it is really being called with bsd43 arguments
X * .. yes, this is fairly gross.
X */
Xint
Xbsd43_sys_ioctl()
X{
X static int ive_been_called_before;
X int result;
X
X if (ive_been_called_before)
X result = -2;
X else
X {
X ive_been_called_before = 1;
X result = sys_ioctl(BSD43_SYS_ioctl);
X }
X
X ive_been_called_before = 0;
X
X return result;
X}
X
Xstatic
Xint
Xsys_lstat(syscallno)
Xint syscallno;
X{
X struct bsd43_stat statb;
X
X return generic_lstat(syscallno, &statb, sizeof(statb));
X}
X
Xstatic
Xint
Xsys_mount(syscallno)
Xint syscallno;
X{
X char *typenamep;
X char typename[1024];
X char *dirnamep;
X char dirname[1024];
X char *normal_argsp;
X char normal_args[1024];
X struct bsd43_nfs_args nfsargs;
X /*
X * Should be:
X
X struct bsd43_sockaddr_in sock;
X
X * but there doesn't seem to be such
X * a definition in any of the include
X * files I've looked through, so...
X */
X struct sockaddr_in sock;
X fhandle_t fh;
X char *data;
X char shostname[HOSTNAMESZ];
X char snetname[MAXNETNAMELEN + 1];
X
X if (mgets(arg[0], &typenamep) == -1)
X return -1;
X
X if (typenamep != (char *)0)
X {
X (void)strcpy(&typename[0], typenamep);
X typenamep = &typename[0];
X }
X
X if (mgets(arg[1], &dirnamep) == -1)
X return -1;
X
X if (dirnamep != (char *)0)
X {
X (void)strcpy(&dirname[0], dirnamep);
X dirnamep = &dirname[0];
X }
X
X if
X (
X strcmp(&typename[0], "ffs") == 0
X ||
X strcmp(&typename[0], "ufs") == 0
X ||
X strcmp(&typename[0], "4.3") == 0
X )
X {
X if (mgets(arg[3], &normal_argsp) == -1)
X return -1;
X
X if (normal_argsp != (char *)0)
X {
X (void)strcpy(&normal_args[0], normal_argsp);
X normal_argsp = &normal_args[0];
X }
X
X data = normal_argsp;
X }
X else /* "nfs" */
X {
X if (quiet_procmget(GLOBALdipc, (unsigned long)arg[3], &nfsargs, sizeof(nfsargs)) == -1)
X return -1;
X
X if (quiet_procmget(GLOBALdipc, (unsigned long)nfsargs.addr, &sock, sizeof(sock)) == -1)
X return -1;
X
X /*
X * This cast is wrong but see comment
X * above at start of this routine.
X */
X *(char **)&nfsargs.addr = (char *)&sock;
X
X if (quiet_procmget(GLOBALdipc, (unsigned long)nfsargs.fh, &fh, sizeof(fh)) == -1)
X return -1;
X
X nfsargs.fh = (caddr_t)&fh;
X
X if (nfsargs.flags & BSD43_NFSMNT_HOSTNAME)
X {
X if (quiet_procmget(GLOBALdipc, (unsigned long)nfsargs.bsd43_hostname, &shostname[0], sizeof(shostname)) == -1)
X return -1;
X
X nfsargs.bsd43_hostname = &shostname[0];
X }
X
X if (nfsargs.flags & BSD43_NFSMNT_SECURE)
X {
X if (quiet_procmget(GLOBALdipc, (unsigned long)nfsargs.netname, &snetname[0], sizeof(snetname)) == -1)
X return -1;
X
X nfsargs.netname = &snetname[0];
X }
X
X data = (char *)&nfsargs;
X }
X
X Rstart;
X return_value0 = syscall(syscallno, typenamep, dirnamep, (int)arg[2], (int)data);
X return_errno = errno;
X Rstop;
X
X return 0;
X}
X
Xstatic
Xint
Xsys_pipe(syscallno)
Xint syscallno;
X{
X /*
X * TODO: do real bsd43 syscall for pipe()
X */
X int fds[2];
X
X Rstart;
X return_value0 = pipe(&fds[0]);
X return_errno = errno;
X Rstop;
X
X if (return_value0 != -1)
X {
X return_value0 = fd_open(fds[0]);
X return_value1 = fd_open(fds[1]);
X }
X
X return 0;
X}
X
Xstatic
Xint
Xsys_readv(syscallno)
Xint syscallno;
X{
X struct bsd43_iovec *saved_iov;
X struct bsd43_iovec *iov;
X int iovcnt;
X int i;
X
X iovcnt = arg[2];
X
X /*
X * Copy in the scatter/gather array.
X */
X if ((struct bsd43_iovec *)arg[1] != (struct bsd43_iovec *)0)
X {
X if ((iov = (struct bsd43_iovec *)malloc(iovcnt * sizeof(*iov))) == (struct bsd43_iovec *)0)
X {
X vcouldnot("allocate buffer for scatter/gather vector of %d elements", iovcnt);
X return -1;
X }
X
X if (quiet_procmget(GLOBALdipc, (unsigned long)arg[1], iov, (unsigned int)iovcnt * sizeof(*iov)) == -1)
X return -1;
X
X /*
X * Save a copy of the array.
X */
X if ((saved_iov = (struct bsd43_iovec *)malloc(iovcnt * sizeof(*iov))) == (struct bsd43_iovec *)0)
X {
X vcouldnot("allocate buffer for saved scatter/gather vector of %d elements", iovcnt);
X return -1;
X }
X
X (void)memcpy(saved_iov, iov, iovcnt * sizeof(*iov));
X
X /*
X * Copy in each entry of the array.
X */
X for (i = 0; i < iovcnt; i++)
X {
X struct bsd43_iovec *liovp;
X
X liovp = &iov[i];
X
X if (liovp->iov_base != (caddr_t)0)
X {
X caddr_t b;
X
X if ((b = (caddr_t)malloc(liovp->iov_len)) == (caddr_t)0)
X {
X vcouldnot("allocate buffer for member of scatter/gather vector of %d bytes", liovp->iov_len);
X return -1;
X }
X
X if (quiet_procmget(GLOBALdipc, (unsigned long)liovp->iov_base, b, (unsigned int)liovp->iov_len) == -1)
X return -1;
X
X liovp->iov_base = b;
X }
X }
X }
X
X Rstart;
X return_value0 = syscall(syscallno, fd_lookup((int)arg[0]), iov, iovcnt);
X return_errno = errno;
X Rstop;
X
X /*
X * Copy out fields to the user, free()'ing as we go.
X */
X
X /*
X * Copy out the scatter/gather array.
X */
X if ((struct bsd43_iovec *)(arg[1]) != (struct bsd43_iovec *)0)
X {
X /*
X * Copy out each entry of the array.
X */
X for (i = 0; i < iovcnt; i++)
X {
X struct bsd43_iovec *liovp;
X
X liovp = &iov[i];
X
X if (saved_iov[i].iov_base != (caddr_t)0)
X {
X if (quiet_procmput(GLOBALdipc, (unsigned long)saved_iov[i].iov_base, liovp->iov_base, (unsigned int)liovp->iov_len) == -1)
X return -1;
X
X (void)free(liovp->iov_base);
X }
X }
X
X (void)free(saved_iov);
X
X /*
X * Copy out the reconstructed array itself?
X */
X
X (void)free(iov);
X }
X
X return 0;
X}
X
Xstatic
Xint
Xsys_recvfrom(syscallno)
Xint syscallno;
X{
X struct bsd43_sockaddr from;
X
X return generic_recvfrom(syscallno, &from);
X}
X
Xstatic
Xint
Xsys_recvmsg(syscallno)
Xint syscallno;
X{
X struct bsd43_msghdr local_msghdr;
X struct bsd43_msghdr saved_local_msghdr;
X struct bsd43_iovec *saved_msg_iov;
X
X if (quiet_procmget(GLOBALdipc, (unsigned long)arg[1], &local_msghdr, sizeof(local_msghdr)) == -1)
X return -1;
X
X saved_local_msghdr = local_msghdr;
X
X /*
X * Copy in the optional address.
X */
X if (local_msghdr.msg_name != (caddr_t)0)
X {
X caddr_t name;
X
X if ((name = (caddr_t)malloc(local_msghdr.msg_namelen)) == (caddr_t)0)
X {
X vcouldnot("allocate buffer for msg_name of length %d bytes", local_msghdr.msg_namelen);
X return -1;
X }
X
X if (quiet_procmget(GLOBALdipc, (unsigned long)local_msghdr.msg_name, name, (unsigned int)local_msghdr.msg_namelen) == -1)
X return -1;
X
X local_msghdr.msg_name = name;
X }
X
X /*
X * Copy in the scatter/gather array.
X */
X if (local_msghdr.msg_iov != (struct bsd43_iovec *)0)
X {
X struct bsd43_iovec *v;
X int i;
X
X if ((v = (struct bsd43_iovec *)malloc(local_msghdr.msg_iovlen * sizeof(*v))) == (struct bsd43_iovec *)0)
X {
X vcouldnot("allocate buffer for scatter/gather vector of %d elements", local_msghdr.msg_iovlen);
X return -1;
X }
X
X if (quiet_procmget(GLOBALdipc, (unsigned long)local_msghdr.msg_iov, v, (unsigned int)local_msghdr.msg_iovlen * sizeof(*v)) == -1)
X return -1;
X
X local_msghdr.msg_iov = v;
X
X /*
X * Save a copy of the array.
X */
X if ((saved_msg_iov = (struct bsd43_iovec *)malloc(local_msghdr.msg_iovlen * sizeof(*v))) == (struct bsd43_iovec *)0)
X {
X vcouldnot("allocate buffer for saved scatter/gather vector of %d elements", local_msghdr.msg_iovlen);
X return -1;
X }
X
X (void)memcpy(saved_msg_iov, v, local_msghdr.msg_iovlen * sizeof(*v));
X
X /*
X * Copy in each entry of the array.
X */
X for (i = 0; i < local_msghdr.msg_iovlen; i++)
X {
X struct bsd43_iovec *liovp;
X
X liovp = &(local_msghdr.msg_iov[i]);
X
X if (liovp->iov_base != (caddr_t)0)
X {
X caddr_t b;
X
X if ((b = (caddr_t)malloc(liovp->iov_len)) == (caddr_t)0)
X {
X vcouldnot("allocate buffer for member of scatter/gather vector of %d bytes", liovp->iov_len);
X return -1;
X }
X
X if (quiet_procmget(GLOBALdipc, (unsigned long)liovp->iov_base, b, (unsigned int)liovp->iov_len) == -1)
X return -1;
X
X liovp->iov_base = b;
X }
X }
X }
X
X /*
X * Copy in the optional(?) access rights.
X */
X if (local_msghdr.msg_accrights != (caddr_t)0)
X {
X caddr_t a;
X
X if ((a = (caddr_t)malloc(local_msghdr.msg_accrightslen)) == (caddr_t)0)
X {
X vcouldnot("allocate buffer for access rights of length %d bytes", local_msghdr.msg_accrightslen);
X return -1;
X }
X
X if (quiet_procmget(GLOBALdipc, (unsigned long)local_msghdr.msg_accrights, a, (unsigned int)local_msghdr.msg_accrightslen) == -1)
X return -1;
X
X local_msghdr.msg_accrights = a;
X }
X
X Rstart;
X return_value0 = syscall(syscallno, fd_lookup((int)arg[0]), &local_msghdr, (int)arg[2]);
X return_errno = errno;
X Rstop;
X
X /*
X * Copy out fields to the user, free()'ing as we go.
X */
X
X /*
X * Copy out the access rights.
X */
X if (saved_local_msghdr.msg_accrights != (caddr_t)0)
X {
X if (quiet_procmput(GLOBALdipc, (unsigned long)saved_local_msghdr.msg_accrights, local_msghdr.msg_accrights, (unsigned int)local_msghdr.msg_accrightslen) == -1)
X return -1;
X
X (void)free((char *)local_msghdr.msg_accrights);
X }
X
X /*
X * Copy out the scatter/gather array.
X */
X if (saved_local_msghdr.msg_iov != (struct bsd43_iovec *)0)
X {
X int i;
X
X /*
X * Copy out each entry of the array.
X */
X for (i = 0; i < local_msghdr.msg_iovlen; i++)
X {
X struct bsd43_iovec *liovp;
X
X liovp = &(local_msghdr.msg_iov[i]);
X
X if (saved_msg_iov[i].iov_base != (caddr_t)0)
X {
X if (quiet_procmput(GLOBALdipc, (unsigned long)saved_msg_iov[i].iov_base, liovp->iov_base, (unsigned int)liovp->iov_len) == -1)
X return -1;
X
X (void)free(liovp->iov_base);
X }
X }
X
X (void)free(saved_msg_iov);
X
X /*
X * Copy out the reconstructed array itself?
X */
X
X (void)free(local_msghdr.msg_iov);
X }
X
X /*
X * Copy out the received name and its length?
X */
X
X (void)free(local_msghdr.msg_name);
X
X return 0;
X}
X
X#define select_dget(a,d,pp,m,nm) \
X{ \
X if (a == 0) \
X pp = (struct bsd43_fd_set *)0; \
X else \
X { \
X struct bsd43_fd_set tfds; \
X int fd; \
X \
X if (quiet_procmget(GLOBALdipc, (unsigned long)a, &tfds, howmany(m, NFDBITS) * sizeof(bsd43_fd_mask)) == -1) \
X return -1; \
X \
X BSD43_FD_ZERO(&d); \
X \
X for (fd = 0; fd < m; fd++) \
X { \
X int nfd; \
X \
X if \
X ( \
X BSD43_FD_ISSET(fd, &tfds) \
X && \
X (nfd = fd_lookup(fd)) != -1 \
X ) \
X { \
X BSD43_FD_SET(nfd, &d); \
X if (nfd >= nm) \
X nm = nfd + 1; \
X } \
X } \
X \
X pp = &d; \
X } \
X}
X
X#define select_tget(a,d,p,t) \
X{ \
X if (a == 0) \
X p = (t *)0; \
X else \
X { \
X if (quiet_procmget(GLOBALdipc, (unsigned long)a, &d, sizeof(d)) == -1) \
X return -1; \
X \
X p = &d; \
X } \
X}
X
X#define select_dput(a,pp,nn) \
X{ \
X if (a != 0) \
X { \
X struct bsd43_fd_set tfds; \
X int fd; \
X \
X BSD43_FD_ZERO(&tfds); \
X \
X for (fd = 0; fd < nn; fd++) \
X { \
X int nfd; \
X \
X if \
X ( \
X (nfd = fd_lookup(fd)) != -1 \
X && \
X BSD43_FD_ISSET(nfd, pp) \
X ) \
X BSD43_FD_SET(fd, &tfds); \
X } \
X \
X if (quiet_procmput(GLOBALdipc, (unsigned long)a, &tfds, howmany(nn, BSD43_NFDBITS) * sizeof(bsd43_fd_mask)) == -1) \
X return -1; \
X } \
X}
X
Xstatic
Xint
Xsys_select(syscallno)
Xint syscallno;
X{
X struct bsd43_fd_set rfds;
X struct bsd43_fd_set *rfdsp;
X struct bsd43_fd_set wfds;
X struct bsd43_fd_set *wfdsp;
X struct bsd43_fd_set efds;
X struct bsd43_fd_set *efdsp;
X struct bsd43_timeval timeout;
X struct bsd43_timeval *timeoutp;
X int nfds;
X int newnfds;
X
X nfds = (int)arg[0];
X if (nfds > fd_nfiles())
X nfds = fd_nfiles();
X newnfds = 0;
X
X select_dget(arg[1], rfds, rfdsp, nfds, newnfds);
X select_dget(arg[2], wfds, wfdsp, nfds, newnfds);
X select_dget(arg[3], efds, efdsp, nfds, newnfds);
X select_tget(arg[4], timeout, timeoutp, struct bsd43_timeval);
X
X Rstart;
X return_value0 = syscall(syscallno, newnfds, rfdsp, wfdsp, efdsp, timeoutp);
X return_errno = errno;
X Rstop;
X
X if (return_value0 != -1)
X {
X select_dput(arg[3], efdsp, nfds);
X select_dput(arg[2], wfdsp, nfds);
X select_dput(arg[1], rfdsp, nfds);
X }
X
X return 0;
X}
X
Xstatic
Xint
Xsys_sendmsg(syscallno)
Xint syscallno;
X{
X struct bsd43_msghdr local_msghdr;
X
X if (quiet_procmget(GLOBALdipc, (unsigned long)arg[1], &local_msghdr, sizeof(local_msghdr)) == -1)